﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using Fuse8.ContentManagementFramework.BizFacade.Services;
using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.Common.Locator;

using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Web.MvcPowered;

namespace Fuse8.ContentManagementFramework.Web.Etc
{
    public static class UIHtmlHelpers
    {
        public static string JsGlobal(this HtmlHelper helper, string fileName)
        {            
            return JsGlobal(helper, fileName, string.Empty);
        }

        public static string JsGlobal(this HtmlHelper helper, string fileName, string cdnUrl)
        {
            return JsGlobalFrom(helper, string.Empty, fileName, cdnUrl);
        }

        public static string JsGlobalFrom(this HtmlHelper helper, string virtualDirectory, string fileName)
        {
            return JsGlobalFrom(helper, virtualDirectory, fileName, string.Empty);
        }

        public static string JsGlobalFrom(this HtmlHelper helper, string virtualDirectory, string fileName, string cdnUrl)
        {
            Guard.ArgumentNotNull(helper, "helper");
            Guard.ArgumentNotEmpty(fileName, "fileName");

            return !helper.ViewContext.HttpContext.IsDebuggingEnabled && !string.IsNullOrWhiteSpace(cdnUrl) ?
                cdnUrl :
                !string.IsNullOrWhiteSpace(virtualDirectory) ?
                    string.Format("/{0}/assets/js/global/{1}", virtualDirectory, fileName) :
                    string.Format("/assets/js/global/{0}", fileName);
        }

        public static string RelativePathToAbsolute (this HtmlHelper helper, string url)
        {
            Guard.ArgumentNotNull(helper, "helper");
            Guard.ArgumentNotNull(url, "url");

            var currentUrl = helper.ViewContext.HttpContext.Request.Url;
            return new Uri(currentUrl, url).AbsoluteUri;
        }

        public static IHtmlString PageControlEditor(this HtmlHelper helper, CmsPageControl pageControl)
        {
            Guard.ArgumentNotNull(helper, "helper");
            Guard.ArgumentNotNull(pageControl, "pageControl");

            MvcHtmlString result = null;

            try
            {
                switch (pageControl.CommonPageControlType)
                {
                    case PageControlTypeKind.MvcPartial:
                    case PageControlTypeKind.ModulePart:
                        var mvcPartialParameters = pageControl.GetCmsMvcPartialControlParameters();

                        var model = new CmsMvcPartialAdministrationModel
                                        {
                                            PageControlId = pageControl.Id,
                                            PartialViewName = mvcPartialParameters.PartialViewName,
                                            PartialAdministrationViewName =
                                                mvcPartialParameters.PartialAdministrationViewName,
                                            PartialModelType = mvcPartialParameters.PartialModelType,
                                            PartialViewModel = mvcPartialParameters.PartialViewModel,
                                            ModuleId = mvcPartialParameters.ModuleId,
                                            ModuleName = mvcPartialParameters.ModuleName,
                                        };

                        if (pageControl.CommonPageControlType == PageControlTypeKind.ModulePart)
                        {
                            model.ModuleDescription = mvcPartialParameters.ModuleDescription;
                        }
                        result = helper.Partial("MvcPartialEditor", model);                       
                        break;
                    case PageControlTypeKind.ContentModule:
                    case PageControlTypeKind.MvcAction:
                        var mvcActionParameters = pageControl.GetCmsMvcPartialControlParameters();

                        result = helper.Partial(
                                "MvcActionEditor",
                                new CmsMvcPartialAdministrationModel
                                {
                                    PageControlId = pageControl.Id,
                                    ActionController = mvcActionParameters.ActionController,
                                    ActionName = mvcActionParameters.ActionName,
                                    PartialAdministrationViewName = mvcActionParameters.PartialAdministrationViewName,
                                    PartialModelType = mvcActionParameters.PartialModelType,
                                    PartialViewModel = mvcActionParameters.PartialViewModel
                                });

                        break;
                }
            }
            catch (Exception ex)
            {
                result = helper.Partial(
                                "ErrorInPageControl",
                                new
                                {
                                    PageControlId = pageControl.Id,
                                    ErrorMessage = ex.InnerException != null ? string.Format("{0} : {1}", ex.Message, ex.InnerException) : ex.Message
                                }.ToExpando());
            }

            return result;
        }

        public static CmsUser CurrentUser(this HttpRequestBase request)
        {
            Guard.ArgumentNotNull(request, "request");

            return DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextUser;
        }

        public static CmsSite CurrentSite(this HttpRequestBase request)
        {
            Guard.ArgumentNotNull(request, "request");

            return DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextSite;
        }

        public static string CurrentHost(this HttpRequestBase request)
        {
            Guard.ArgumentNotNull(request, "request");

            var site = CurrentSite(request);
            if (site.Domains == null) return request.ApplicationPath;
            var domain = site.Domains.FirstOrDefault();
            // what if https?
            return domain != null ? string.Format("http://{0}", domain.Hostname) : request.ApplicationPath; 
        }

        public static IEnumerable<CmsSite> AvailableSitesForCurrentUser(this HttpRequestBase request)
        {
            // TODO possibly move this method to CmsAdminController because it creates a service instance
            Guard.ArgumentNotNull(request, "request");

            var sites = new CmsSiteService().FindAvailableByUser(request.CurrentUser());

            return sites;
        }   
    }
}
